<?php

namespace app\common\model;

use mailer\lib\Exception;
use think\Db;

class ShopOrderModel extends BaseModel
{
    protected $name = 'shop_order'; //定义用户表
    //开启自动写入时间戳
    protected $autoWriteTimestamp = false;
    // 定义自动完成的属性
    protected $auto = []; //新增修改
    protected $insert = []; //插入
    protected $update = []; //修改

    //读取器
    protected function getAreaTextAttr($value, $data)
    {
        $area = cache('area');
        return $area[$data['prov_id']] . ' ' . $area[$data['city_id']] . ' ' . $area[$data['dist_id']];
    }

    protected function getOrderStatusTextAttr($value, $data)
    {
        $orderStatus = ['-1' => '已关闭', '0' => '待确认', '1' => '已确认', '2' => '已完成'];
        return $orderStatus[$data['order_status']];
    }

    protected function getPayStatusTextAttr($value, $data)
    {
        $payStatus = ['0' => '待付款', '1' => '已付款'];
        return $payStatus[$data['pay_status']];
    }

    protected function getShippingStatusTextAttr($value, $data)
    {
        $shippingStatus = ['0' => '未发货', '1' => '已发货'];
        return $shippingStatus[$data['shipping_status']];
    }

    //格式化发票信息
    protected function getInvoiceInfoAttr($value)
    {
        if (empty($value)) {
            return [];
        } else {
            return json_decode($value, true);
        }
    }

    /**
     * 提交订单
     * @param int $orderType 0普通订单 1自提订单 3积分订单
     * @param array $skuIds 商品skuid
     * @param int $BuyerUid 购买用户
     * @param integer $siteId 站点id
     * @param int $addressId 收获信息id
     * @param string $orderMessage 订单备注
     * @param int $deliveryId 运费id,如果是0则运费为0
     * @param int $invId 开票信息ID
     * @param string $cardKey 卡卷号
     * @param int $payCode 支付方式
     */
    public function subOrder($orderType, $skuIds, $buyerUid, $siteId, $addressId, $orderMessage, $deliveryId, $invId, $cardKey, $payCode = '')
    {
        $cartModel = new ShopCartModel();
        $end       = $cartModel->refreshCart($buyerUid, $siteId); //刷新购物车
        if (!$end) {
            $this->error = '部分商品库存不足或者活动已结束';
            return false;
        }
        $userModel          = new UserModel();
        $memberModel        = new UserMemberModel();
        $paymentModel       = new ShopPaymentModel();
        $shopDeliveryModel  = new ShopDeliveryModel();
        $promotionCardModel = new ShopCardModel();
        $addressModel       = new UserAddressModel();
        $orderGoodsModel    = new ShopOrderGoodsModel();
        //准备数据
        $orderSn       = rand_number();
        $buyerUsername = $userModel->where('uid', $buyerUid)->value('username');
        $payName       = '';
        if (!empty($payCode)) {
            $payName = $paymentModel->where('pay_code', $payCode)->value('pay_name');
        }
        $cart = $cartModel->cartList($siteId, $buyerUid, $skuIds);
        if(empty($cart)){
            $this->error = '订单提交数据为空！';
            return false;
        }
        $siteName = $cart['site_name'];
        $cartList = $cart['item_list'];
        //判断积分状态
        if ($orderType == 3) {
            $userPoint = $memberModel->where('uid', $buyerUid)->value('pay_points');
            if ($userPoint < $cart['total_goods_point']) {
                $this->error = '您得可用积分不足！';
                return false;
            }
        }
        $goodsAmount    = $cart['total_price']; //商品总价
        $orderGivePoint = $orderType == 3 ? 0 : $cart['total_give_point']; //订单赠送积分
        $orderPayPoint  = $orderType == 3 ? $cart['total_goods_point'] : 0; //订单消费积分
        $deliveryName   = '';
        if ($deliveryId > 0) {
            //计算运费
            $skuIdsWeight = [];
            foreach ($cartList as $k => $v) {
                $skuIdsWeight[$v['sku_id']] = $v['num'];
            }
            $deliveryName = $shopDeliveryModel->where('delivery_id', $deliveryId)->value('delivery_name');
            $shippingFee  = $shopDeliveryModel->calculateFreight($skuIdsWeight, $deliveryId, $goodsAmount); //配送费
        } else {
            $shippingFee = 0;
        }
        $cardPrice = 0;
        if (!empty($cardKey)) { //获取优惠券订单计算金额
            $cardPrice = $promotionCardModel->getCardPrice($cardKey, $goodsAmount);
        }
        $orderPrice = ($goodsAmount + $shippingFee - $cardPrice);
        //订单主表数据
        $orderInfo = [
            'order_sn'         => $orderSn,
            'site_id'          => $siteId,
            'site_name'        => $siteName,
            'buyer_uid'        => $buyerUid,
            'buyer_username'   => $buyerUsername,
            'pay_code'         => $payCode,
            'pay_name'         => $payName,
            'goods_amount'     => $goodsAmount,
            'shipping_fee'     => $shippingFee,
            'card_key'         => $cardKey,
            'card_price'       => $cardPrice,
            'order_price'      => $orderPrice,
            'order_pay_point'  => $orderPayPoint,
            'order_give_point' => $orderGivePoint,
            'order_status'     => 0,
            'shipping_status'  => 0,
            'pay_status'       => 0,
            'refund_status'    => 0,
            'order_message'    => $orderMessage,
            'order_from'       => is_mobile(), //1手机端 2电脑端 3微信端
            'order_type'       => $orderType,
            'create_time'      => time(),
            'delivery_name'    => $deliveryName,
        ];
        //自提订单
        if ($orderType == 1) {
            $orderInfo['shipping_code'] = rand_number(); //生成自提单号
        }
        //处理收货地址
        if ($addressId > 0) {
            $addressInfo = $addressModel->where('address_id', $addressId)->find()->toArray();
            $orderInfo   = array_merge($orderInfo, $addressInfo);
            unset($orderInfo['address_id'], $orderInfo['uid'], $orderInfo['is_default']);
        }
        //处理发票信息
        $orderInfo['invoice'] = 0;
        if ($invId > 0) { //发票信息
            $invoiceModel = new ShopInvoiceModel();
            $invoiceInfo  = $invoiceModel->get($invId);
            if ($invoiceInfo) {
                $orderInfo['invoice']      = 1;
                $orderInfo['invoice_info'] = json_encode($invoiceInfo);
            }
        }
        //保存主表数据
        $this->save($orderInfo);
        $orderId = $this->getData('order_id');
        //核销卡券
        if (!empty($cardKey)) {
            $promotionCardModel->useCard($cardKey, $orderId, $goodsAmount, $cardPrice);
        }
        //从表数据
        $orderGoodsList = [];
        foreach ($cartList as $item => $value) {
            $orderGoodsList[] = [
                'order_id'       => $orderId,
                'sku_id'         => $value['sku_id'],
                'goods_id'       => $value['goods_id'],
                'site_id'        => $siteId,
                'buyer_uid'      => $buyerUid,
                'sku_sn'         => $value['sku_sn'],
                'goods_name'     => $value['goods_name'],
                'sku_name'       => $value['sku_name'],
                'goods_unit'     => $value['goods_unit'],
                'goods_thumb'    => $value['goods_thumb'],
                'pay_point'      => $value['goods_point'],
                'give_point'     => $value['give_point'],
                'goods_price'    => $value['goods_price'],
                'unit_price'     => $value['price'],
                'goods_num'      => $value['num'],
                'pay_price'      => $value['num'] * $value['price'],
                'promotion_id'   => $value['promotion_id'],
                'promotion_type' => $value['promotion_type'],
            ];
        }
        $orderGoodsModel->saveAll($orderGoodsList);
        //删除购物车对应数据
        $cartModel->where('sku_id', 'in', $skuIds)->where('member_uid', $buyerUid)->delete();
        //添加订单日志表
        $orderLogModel = new ShopOrderLogModel();
        $orderLogModel->addOrderLog($buyerUsername, $orderId, 0, 0, 0, "{$buyerUsername}提交了订单！");
        //处理积分
        if ($orderType == 3) { //积分订单预先扣除用户消费得积分
            $account['pay_points']  = $orderPayPoint * -1;
            $userMemberAccountModel = new UserMemberAccountModel();
            $userMemberAccountModel->changeAccount($siteId, 0, $buyerUid, $orderId, $account, '3', "{$buyerUsername}提交订单扣除消费积分！");
        }
        return $orderSn;
    }

    /**
     * 确认订单
     * @param $orderIds
     */
    public function confirmOrder($actionName, $orderIds)
    {
        $orderList = $this->where('order_id', 'in', $orderIds)->where('order_status', 0)->select();
        if ($orderList->isEmpty()) {
            $this->error = '没有需要确认得订单!';
            return false;
        }
        foreach ($orderList as $k => $v) {
            $data['order_status'] = 1;
            if ($v['order_type'] == 1) { //自提订单不需要发货,标记为已发货
                $data['shipping_status'] = 1;
            }
            $this->where('order_id', $v['order_id'])->update($data);
            //写入日志
            $orderLogModel = new ShopOrderLogModel();
            $orderLogModel->addOrderLog($actionName, $v['order_id'], 1, $data['shipping_status'], $v['pay_status'], $actionName . '确认了订单');
            return true;
        }
        return true;
    }

    /**
     * 订单付款
     * @param $actionName
     * @param $data
     * @return bool
     */
    public function payOrder($actionName, $orderSn, $payCode, $logMsg, $paymentTime = 0)
    {
        $orderInfo = $this->where('order_sn', $orderSn)->find();
        if ($orderInfo['pay_status'] == 0) {
            $payName     = Db::table('shop_payment')->where('pay_code', $payCode)->value('pay_name');
            $paymentTime = $paymentTime > 0 ? $paymentTime : time();
            $orderData   = [
                'order_id' => $orderInfo['order_id'],
                'pay_code' => $payCode,
                'pay_name' => $payName,
            ];
            //排除货到付款
            if ($payCode != 'delivery') {
                $orderData['payment_time'] = $paymentTime;
                $orderData['pay_status']   = 1;
                $orderData['pay_price']    = $orderInfo['order_price'];
            }
            $this->editData($orderData);
            //写入日志
            $orderLogModel = new ShopOrderLogModel();
            $orderLogModel->addOrderLog($actionName, $orderInfo['order_id'], $orderInfo['order_status'], $orderInfo['shipping_status'], $orderInfo['pay_status'], $logMsg);
            return true;
        } else {
            $this->error = '该订单已付款！';
            return false;
        }
    }

    /**
     * 订单发货
     */
    public function deliveryOrder($actionName, $data)
    {
        $orderInfo = $this->get($data['order_id']);
        if ($orderInfo['shipping_status'] == 0 && $orderInfo['order_status'] == 1) {
            $express     = cache('express');
            $expressName = $express[$data['express_code']]['express_name'];
            $orderData   = [
                'order_id'        => $data['order_id'],
                'shipping_time'   => strtotime($data['shipping_time']),
                'express_name'    => $expressName,
                'express_code'    => $data['express_code'],
                'shipping_code'   => $data['shipping_code'],
                'deliver_explain' => $data['deliver_explain'],
                'shipping_status' => 1,
            ];
            $this->editData($orderData);
            //扣减库存
            $orderGoodsModel = new ShopOrderGoodsModel();
            $saleData        = $orderGoodsModel->where('order_id', $orderInfo['order_id'])->column('goods_num', 'sku_id');
            $orderGoodsModel->doStock($saleData, 1);
            //写入日志
            $orderLogModel = new ShopOrderLogModel();
            $orderLogModel->addOrderLog($actionName, $data['order_id'], $orderInfo['order_status'], 1, $orderInfo['pay_status'], $data['deliver_explain']);
            return true;
        } else {
            $this->error = '只有已确认未配送得订单才可以发货！';
            return false;
        }
    }

    /**
     * 完成订单
     * @param $actionName
     * @param $data
     */
    public function finnshedOrder($actionName, $orderId)
    {
        $orderInfo = $this->get($orderId);
        if ($orderInfo['shipping_status'] == 1 && $orderInfo['order_status'] == 1) {
            if ($orderInfo['pay_code'] != 'delivery') { //非货到付款要判断支付状态
                if ($orderInfo['pay_status'] != 1) {
                    $this->error = '该订单还未支付！';
                    return false;
                }
            }
            $orderData = [
                'order_id'      => $orderId,
                'finnshed_time' => time(),
                'order_status'  => 2,
            ];
            $this->editData($orderData);
            //增加赠送积分
            if ($orderInfo['order_give_point'] > 0) {
                $account['pay_points']  = $orderInfo['order_give_point'];
                $userMemberAccountModel = new UserMemberAccountModel();
                $userMemberAccountModel->changeAccount($orderInfo['site_id'], 0, $orderInfo['buyer_uid'], $orderId, $account, '5', "订单完成赠送积分！");
            }
            //写入日志
            $logMsg        = '订单[' . $orderInfo['order_sn'] . ']已签收';
            $orderLogModel = new ShopOrderLogModel();
            $orderLogModel->addOrderLog($actionName, $orderId, 2, $orderInfo['shipping_status'], $orderInfo['pay_status'], $logMsg);
            return true;
        } else {
            $this->error = '只有已发货/已确认订单才可以确认收货！';
            return false;
        }
    }

    /**
     * 关闭订单
     * @param $actionName 操作人
     * @param $orderId
     * @return bool
     */
    public function closeOrder($actionName, $orderId)
    {
        $orderInfo = $this->where('order_id', $orderId)->find();
        if ($orderInfo['shipping_status'] > 0) {
            $this->error = '订单已发货，订单不可关闭';
            return false;
        }
        if ($orderInfo['order_status'] == -1) {
            $this->error = '订单已关闭';
            return false;
        }
        if ($orderInfo['card_key']) { //还原卡券
            $cardModel = new ShopCardModel();
            $cardModel->returnCard($orderInfo['card_key']);
        }
        //关闭订单
        $this->where('order_id', $orderId)->setField('order_status', -1);
        //返还用户消费积分
        if ($orderInfo['order_pay_point'] > 0) {
            $account['pay_points']  = $orderInfo['order_pay_point'];
            $userMemberAccountModel = new UserMemberAccountModel();
            $userMemberAccountModel->changeAccount($orderInfo['site_id'], 0, $orderInfo['buyer_uid'], $orderId, $account, '7', "关闭订单返还消费积分！");
        }
        //写入日志
        $orderLogModel = new ShopOrderLogModel();
        $orderLogModel->addOrderLog($actionName, $orderId, -1, $orderInfo['shipping_status'], $orderInfo['pay_status'], '关闭订单');
        return true;
    }

    /**
     * 增加退款记录
     * @param $actionName
     * @param $data $data=['order_id'=>1,'refund_amount'=>'','refund_type'=>'','buyer_message'=>''];
     */
    public function addRefundOrder($actionName, $data)
    {
        $orderInfo = $this->where('order_id', $data['order_id'])->find();
        if ($data['refund_amount'] > ($orderInfo['pay_price'] - $orderInfo['refund_amount'])) {
            $this->error = '最多可以退款' . ($orderInfo['pay_price'] - $orderInfo['refund_amount']) . '元';
            return false;
        }
        if ($orderInfo['pay_status'] == 1 && $orderInfo['pay_price'] > $orderInfo['refund_amount']) {
            $refundModel = new ShopOrderRefundModel();
            $refundData  = [
                'order_id'       => $orderInfo['order_id'],
                'order_sn'       => $orderInfo['order_sn'],
                'site_id'        => $orderInfo['site_id'],
                'buyer_uid'      => $orderInfo['buyer_uid'],
                'buyer_username' => $orderInfo['buyer_username'],
                'refund_amount'  => $data['refund_amount'],
                'refund_type'    => $data['refund_type'],
                'seller_status'  => 0,
                'refund_status'  => 1,
                'buyer_message'  => $data['buyer_message'],
                'create_time'    => time(),
            ];
            $refundModel->addData($refundData);
            //写入日志
            $orderLogModel = new ShopOrderLogModel();
            $orderLogModel->addOrderLog($actionName, $orderInfo['order_id'], 3, $orderInfo['shipping_status'], $orderInfo['pay_status'], $actionName . '申请订单退款');
            return true;
        } else {
            $this->error = '只有已付款且可退款订单才可以申请退款';
            return false;
        }
    }

    /**
     * 删除订单
     * @param $order_id
     */
    public function delOrder($orderId)
    {
        $orderInfo = $this->where('order_id', $orderId)->find();
        if ($orderInfo['pay_status'] == 1) {
            $this->err_msg = '已支付订单只可以关闭，不允许删除！';
            return false;
        }
        $map['order_id'] = $orderId;
        $cardKey         = $this->where($map)->value('card_key');
        if ($cardKey) { //还原卡券
            $cardModel = new ShopCardModel();
            $cardModel->returnCard($cardKey);
        }
        //返还用户消费积分
        if ($orderInfo['order_pay_point'] > 0) {
            $account['pay_points']  = $orderInfo['order_pay_point'];
            $userMemberAccountModel = new UserMemberAccountModel();
            $userMemberAccountModel->changeAccount($orderInfo['site_id'], 0, $orderInfo['buyer_uid'], $orderId, $account, '7', "删除订单返还消费积分！");
        }
        $this->where($map)->delete();
        ShopOrderGoodsModel::where($map)->delete();
        ShopOrderLogModel::where($map)->delete();
        return true;
    }

    /**
     * 竞拍加入订单
     * @param $skuId
     * @param $addressId //收货地址id
     * @param $orderMessage
     * @param $invId //发票id
     * @param string $payCode //支付方式
     * @return mixed
     * @throws \Exception
     */
    public function auctionOrder($goodsId, $addressId, $orderMessage, $expressId, $invId, $payCode = '')
    {
        $auctionLogModel = new ShopPromotionAuctionLogModel();
        $goodsModel      = new ShopGoodsModel();
        $skuModel        = new ShopGoodsSkuModel();
        $userModel       = new UserModel();
        $siteModel       = new siteModel();
        $paymentModel    = new ShopPaymentModel();
        $addressModel    = new UserAddressModel();
        $orderGoodsModel = new ShopOrderGoodsModel();
        $expressModel    = new ShopExpressModel();
        $invoiceModel    = new ShopInvoiceModel();
        //准备数据
        $siteId                 = $goodsModel->where('goods_id', $goodsId)->value('site_id');
        $auctionLogInfo         = $auctionLogModel->where(['goods_id' => $goodsId, 'winning' => 1])->find();
        $skuId                  = $auctionLogInfo['sku_id'];
        $buyerUsername          = $userModel->where('uid', $auctionLogInfo['member_uid'])->value('username');
        $auctionLogInfo['bond'] = $auctionLogModel->where(['goods_id' => $goodsId, 'pay_type' => 0, 'status' => 1])->value('money');
        $addressInfo            = $addressModel->find($addressId);//地址信息;
        $expressInfo            = $expressModel->find($expressId);//快递公司
        if ($invId == 0) {
            $invInfo = ['invoice' => 0, 'inv_info' => ''];
        } else {
            $invInfo = $invoiceModel->find($invId)->getData();//发票信息
        }
        $skuInfo   = $skuModel->where('sku_id',
            $auctionLogInfo['sku_id'])->find();
        $goodsInfo = $goodsModel->where('goods_id',
            $auctionLogInfo['goods_id'])->find();
        $orderSn   = rand_number();
        if ($siteId == 0) {
            $siteName = "平台自营";
        } elseif ($siteId > 0) {
            $siteName = $siteModel->where('site_id', $siteId)->value('site_name');
        }
        $payName = '';
        if (!empty($payCode)) {
            $payName = $paymentModel->where(['pay_code' => $payCode, 'site_id' => $siteId])->value('pay_name');
        }
        //订单主表数据
        $orderInfo = [
            'order_sn'         => $orderSn,
            'site_id'          => $siteId,
            'site_name'        => $siteName,
            'buyer_uid'        => $auctionLogInfo['member_uid'],
            'buyer_username'   => $buyerUsername,
            'pay_code'         => $payCode,
            'pay_name'         => $payName,
            'goods_amount'     => $auctionLogInfo['money'],
            'shipping_fee'     => 0,
            'card_key'         => '',
            'card_price'       => 0,
            'promotion_amount' => $auctionLogInfo['bond'],
            'promotion_info'   => "保证金抵扣",
            'refund_amount'    => 0,
            'pay_price'        => $auctionLogInfo['money'] - $auctionLogInfo['bond'],
            'order_price'      => $auctionLogInfo['money'],
            'order_pay_point'  => 0,
            'order_give_point' => 0,
            'order_status'     => 0,
            'geval_status'     => 0,
            'shipping_status'  => 0,
            'pay_status'       => 0,
            'refund_status'    => 0,
            'order_message'    => $orderMessage,
            'order_from'       => is_mobile(),
            'consignee'        => $addressInfo['consignee'],
            'prov_id'          => $addressInfo['prov_id'],
            'city_id'          => $addressInfo['city_id'],
            'dist_id'          => $addressInfo['dist_id'],
            'address'          => $addressInfo['address'],
            'zip_code'         => $addressInfo['zip_code'],
            'tel_phone'        => $addressInfo['tel_phone'],
            'express_name'     => $expressInfo['express_name'],
            'express_code'     => $expressInfo['express_code'],
            'shipping_code'    => 0,
            'deliver_explain'  => '',
            'order_type'       => 5,
            'create_time'      => time(),
            'invoice'          => 1,
            'invoice_sn'       => '',
            'invoice_info'     => $invInfo['inv_info'],
            'parent_sn'        => '',
            'voucher'          => '',
        ];
        //保存主表数据
        $this->save($orderInfo);
        $orderId = $this->getData('order_id');
        //从表数据
        $orderGoodsList[] = [
            'order_id'       => $orderId,
            'sku_id'         => $skuId,
            'goods_id'       => $goodsId,
            'site_id'        => $siteId,
            'buyer_uid'      => $auctionLogInfo['member_uid'],
            'sku_sn'         => $skuInfo['sku_sn'],
            'goods_name'     => $goodsInfo['goods_name'],
            'sku_name'       => $skuInfo['sku_name'],
            'goods_unit'     => $goodsInfo['goods_unit'],
            'goods_thumb'    => $goodsInfo['goods_thumb'],
            'goods_price'    => $auctionLogInfo['money'],
            'give_point'     => 0,
            'pay_point'      => 0,
            'unit_price'     => $auctionLogInfo['money'],
            'goods_num'      => $auctionLogInfo['goods_number'],
            'pay_price'      => $auctionLogInfo['money'] - $auctionLogInfo['bond'],
            'promotion_id'   => 0,
            'promotion_type' => 5,
        ];
        $orderGoodsModel->saveAll($orderGoodsList);
        //添加订单日志表
        $orderLogModel = new ShopOrderLogModel();
        $orderLogModel->addOrderLog($buyerUsername, $orderId, 0, 0, 0, "{$buyerUsername}提交了订单！");
        return $orderId;
    }
}